<script setup lang="ts">
import {onMounted, ref} from "vue";
import {Map, View, Feature} from 'ol'
import {readTransform, writeTransform} from "@/utils/gps/gpsTrans";
import { Draw, Modify, Snap } from 'ol/interaction'
import { Polygon, Point, Circle as gCircle, LineString } from 'ol/geom'
import { Style, Fill, Stroke, Icon, Circle as sCircle, Text } from 'ol/style'
import {createLayers} from "@/utils/gps/locaTool";
import { transform } from 'ol/proj'
import SourceVector from 'ol/source/Vector'
import layerVector from 'ol/layer/Vector'
import mapType from "@/utils/gps/mapType";
import {useGetRouteingInfoApi, useRouteingSaveApi} from "@/api/gps/gps";
import {ElButton, ElMessage} from "element-plus";
import start_icon from "@/assets/image/start_icon.png"
import end_icon from "@/assets/image/end_icon.png"

const emit = defineEmits(["submit", "close"])
const props = defineProps({
  routingId: {
    type: String,
    required: false
  },
  edit: {
    type: Boolean,
    required: false,
    default: false
  }
})

const openMap = ref<Map>()
const modify = ref<Modify>()
let source: SourceVector = new SourceVector()
const fenceData = ref<any>()

let linePath: any
let draw: Draw
let snap: Snap
let circleInfo: {center: any, radius: any}
let wCenter: any
let wRadius: any
let center: any

let attributes = {
  enter: true,
  exit: true,
  speedLimit: 0,
}

onMounted(()=>{
  console.log(props.routingId)
  if(props.routingId) {
    useGetRouteingInfoApi(props.routingId).then((res)=>{
      fenceData.value = res.data
      onLoadMap(initMap)
    })
  } else {
    handleClear()
    init()
  }
})

function init(){
  initMap()
  freeHand()
}

/**
 * 初始化围栏
 */
function onLoadMap(callBack: Function){
  const area = areaFormat(fenceData.value.area)
  center = getCenterPoint(area.path)
  const gpsPath = area.path.map((item: any) => [item.lng, item.lat])
  linePath = gpsPath
  const iconFeature = new Feature({
    geometry: new LineString(gpsPath),
    type: 'lineString'
  })
  const startFeature = new Feature({
    geometry: new Point(gpsPath[0]),
    type:'startPoint',
  });
  const endFeature = new Feature({
    geometry: new Point(gpsPath[gpsPath.length-1]),
    type:'endPoint',
  });
  startFeature.setStyle(new Style({
    image: new Icon({
          anchor: [12, 0.5],
          anchorOrigin: 'bottom-left',
          anchorXUnits: 'pixels',
          anchorYUnits: 'pixels',
          src: start_icon
        })
  }))
  endFeature.setStyle(new Style({
    image: new Icon({
      anchor: [12, 0.5],
      anchorOrigin: 'bottom-left',
      anchorXUnits: 'pixels',
      anchorYUnits: 'pixels',
      src: end_icon
    })
  }))
  // iconFeature.setStyle(new Style({
  //   image: new Icon({
  //     // 定义图标锚点
  //     anchor: [12, 0.5],
  //     anchorOrigin: 'bottom-left',
  //     anchorXUnits: 'pixels',
  //     anchorYUnits: 'pixels',
  //     src: start_icon
  //   }),
  //   // fill: new Fill({ color: 'black' }),
  //   stroke: new Stroke({ color: 'black', width: 2 }),
  //   // text: new Text({
  //   //   text: '1',
  //   //   font: '18px "Roboto", Helvetica Neue, Helvetica, Arial, sans-serif',
  //   //   fill: new Fill({ color: 'black' }),
  //   //   stroke: new Stroke({ color: 'black', width: 2 })
  //   // })
  // }))
  source = new SourceVector({
    features: [startFeature,iconFeature,endFeature]
  })
  callBack()
}

/**
 * 初始化地图
 */
function initMap(){
  const layers: any = createLayers(mapType)
  layers.push(new layerVector({
    source: source,
    style: new Style({
      fill: new Fill({
        color: 'rgba(49,173,252, 0.2)',
      }),
      stroke: new Stroke({
        color: '#0099FF',
        width: 3,
      }),
      image: new sCircle({
        radius: 7,
        fill: new Fill({
          color: '#0099FF',
        }),
      }),
    }),
  }))
  openMap.value = new Map({
    target: 'map-fence-s',
    layers: layers,
    view: new View({
      projection: 'EPSG:4326',
      center: [104.07102, 30.666756],
      // 地图缩放最小级别
      minZoom: 5,
      maxZoom: 20,
      // 地图缩放级别
      zoom: 12,
    }),
  })
}

/**
 * 获取围栏中心点
 * @param path
 */
function getCenterPoint(path: any[]) {
  let lng = 0.0
  let lat = 0.0
  for (let i = 0; i < path.length; i++) {
    lng = lng + parseFloat(path[i].lng)
    lat = lat + parseFloat(path[i].lat)
  }
  lng = lng / path.length
  lat = lat / path.length
  return { lng, lat }
}

function freeHand(){
  if(modify.value) openMap.value?.removeInteraction(modify.value)
  modify.value = new Modify({
    source: source,
    insertVertexCondition: ()=> true
  })
  openMap.value?.addInteraction(modify.value)
  modify.value.on("modifyend", (e)=>{
    console.log(e)
    drawingEnd({
      feature: e.features.getArray()[0],
    })
  })
  addInteractions()
}

/**
 * 绘制图形
 */
function addInteractions(){
  if(draw) openMap.value?.removeInteraction(draw)
  if(snap) openMap.value?.removeInteraction(snap)
  draw = new Draw({
    source: source,
    type: "LineString"
  })
  openMap.value?.addInteraction(draw)
  snap = new Snap({ source: source })
  openMap.value?.addInteraction(snap)
  draw.on("drawend", (e)=>{
    drawingEnd(e)
  })
  // mapOnly()
}

/**
 * 绘制完成解析结构
 * @param evt
 */
function drawingEnd(evt: any){
  console.log(evt)
  const geo: any = evt.feature.getGeometry()
  const handle: any = ({
    Circle: () => {
      const circleIn4326 = new gCircle(transform(geo.getCenter(), 'EPSG:3857', 'EPSG:4326'),
          geo.getRadius(), 'XY').transform('EPSG:4326', 'EPSG:3857')
      circleInfo = {
        center: circleIn4326.getCenter(),
        radius: circleIn4326.getRadius()
      }
      wCenter = circleInfo.center
      wRadius = circleInfo.radius
    },
    LineString: () => {
      linePath = geo.getCoordinates()
    },
  })
  handle[geo.getType()]?.()
}

/**
 * 检测是否重复绘制
 */
function mapOnly(){
  draw.on("drawstart", ()=>{
    if (linePath) {
      source?.clear()
      linePath = []
    }
  })
}

function handleSave(){
  const data = {
    companyId: 4,
    name: "test",
    area: "",
    icon: ""
  }
  data.area = `LINESTRING ((${linePath.map((item: any) => {
    const p = writeTransform(item[1], item[0])
    return `${p[0]} ${p[1]}`
  })?.join(', ')}))`
  data.icon = "el-icon-map-location"

  useRouteingSaveApi(data).then(res=>{
    ElMessage.success("路线规划成功")
    emit("submit", res.data)
    emit("close")
  })
}

function areaFormat(area: any) {
  const point = area.match(/[^\(\)]+(?=\))/g)[0].split(', ')
    return {
      type: 'LINESTRING',
      path: point.map((item: any) => {
        const p = readTransform(item.split(' ')[1], item.split(' ')[0])
        return { lng: p[0], lat: p[1] }
      })
    }

}

function handleClear(){
  source?.clear()
}
</script>

<template>
  <div id="map-fence-s" class="map-fence"></div>
  <div class="control" v-if="props.edit">
    <ElButton type="success" @click="handleSave">保存</ElButton>
  </div>
</template>

<style scoped lang="scss">
.map-fence{
  width: 1200px;
  height: 700px;
}
.control{
  background-color: white;
  //width: 200px;
  //height: 100px;
  position: absolute;
  bottom: 20px;
  right: 50px;
}
</style>
